package cn.hellochaos.generator.controller;


import cn.hellochaos.generator.util.FileUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.ResourceLoader;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.beans.factory.annotation.Autowired;
import cn.hellochaos.generator.entity.dto.ResultBean;
import cn.hellochaos.generator.service.FisheryImageService;
import cn.hellochaos.generator.entity.FisheryImage;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;


/**
 * <p>
 * 渔业对应的图片存储信息 前端控制器
 * </p>
 *
 * @author fmy
 * @since 2021-07-22
 * @version v1.0
 */
@Api(tags = "渔业种质图片相关功能实现")
@RestController
@CrossOrigin
@RequestMapping("/fishery/api/v1/fisheryImage")
@Slf4j
public class FisheryImageController {
    /**
     * 注入spring带的资源读取器
     */
    @Autowired
    private ResourceLoader resourceLoader;
    @Autowired
    private FisheryImageService fisheryImageService;
    //使用什么语法读取配置文件中的路径值值？  就是外层 ${ },内层就是.值表示递进关系
    @Value("${spring.resources.static-locations}")
    private String configImgPath;

    /**
    * 查询分页数据，图片应该暂时用不上
    */
    @ApiOperation("分页查询所有数据")
    @ApiImplicitParams({
    @ApiImplicitParam(name="page",value="页号",required=false,paramType="query",dataType="Integer"),
    @ApiImplicitParam(name="pageSize",value="页大小",required=false,paramType="query",dataType="Integer"),
    @ApiImplicitParam(name="factor",value="条件查询值（根据条件后端可以修改,默认不传）",required=false,paramType="query",dataType="String")
    })
    @RequestMapping(method = RequestMethod.GET,produces = "application/json;charset=UTF-8")
    public ResultBean<?> listByPage(@RequestParam(name = "page", defaultValue = "1") int page,
                                    @RequestParam(name = "pageSize", defaultValue = "10") int pageSize,
                                    @RequestParam(name = "factor", defaultValue = "") String factor) {



        return new ResultBean<>(fisheryImageService.listFisheryImagesByPage(page, pageSize,factor));
    }
    /**
    * 根据id查询
    */
    @ApiOperation("查询图片的数据信息，不是图片本身")
    @ApiImplicitParams({
    @ApiImplicitParam(name="id",value="id的值",required=true,paramType="path",dataType="Integer")
    })
    @RequestMapping(method = RequestMethod.GET, value = "/{id}",produces = "application/json;charset=UTF-8")
    public ResultBean<?> getById(@PathVariable("id") Integer id) {
        return new ResultBean<>(fisheryImageService.getFisheryImageById(id));
    }
    /**
    * 新增
    */
    @ApiOperation("上传一条鱼类图片数据")
    @RequestMapping(method = RequestMethod.POST,produces = "application/json;charset=UTF-8")
    public ResultBean<?> insert(@RequestBody FisheryImage fisheryImage) {
        return new ResultBean<>(fisheryImageService.insertFisheryImage(fisheryImage));
    }

    /**
    * 删除
    */
    @ApiOperation("删除一条鱼类图片数据")
    @RequestMapping(method = RequestMethod.DELETE, value = "/{id}",produces = "application/json;charset=UTF-8")
    public ResultBean<?> deleteById(@PathVariable("id") Integer id) {
        return new ResultBean<>(fisheryImageService.deleteFisheryImageById(id));
    }

    /**
    * 修改
    */
    @ApiOperation("更新一条鱼类图片数据")
    @RequestMapping(method = RequestMethod.PUT,produces = "application/json;charset=UTF-8")
    public ResultBean<?> updateById(@RequestBody FisheryImage fisheryImage) {
        return new ResultBean<>(fisheryImageService.updateFisheryImage(fisheryImage));
    }

    /**
     * 根据图片id显示单张图片，从DB查出路径，磁盘读取并返回
     * @return produces = MediaType.IMAGE_JPEG_VALUE
     * MediaType.APPLICATION_OCTET_STREAM_VALUE,转移到service里
     */
    @ApiOperation("根据图片id获取能显示的图片数据,根据第一次请求得到三种图片对应的id,再做第二次请求")
    @ApiImplicitParams({
            @ApiImplicitParam(name="imageId",value="imageId的值",required=true,paramType="path",dataType="Integer")
    })
    @RequestMapping(method = RequestMethod.GET, value = "/getStreamByImageId/{imageId}",produces= MediaType.APPLICATION_OCTET_STREAM_VALUE)
    public ResponseEntity displayImagesByImageId(@PathVariable("imageId")int imageId){
        //to do :先获取id,在query得到name,在用name得到图片传给b端
        String serverFilePath;
        try {
            //"file:"可以直接写在配置文件里
            // 由于是读取本机的文件，必须要有file：,imgPath是在application配置文件中的路径 +"/"
            //放在linux上可能就不要了
            serverFilePath=fisheryImageService.getImagePathByImageId(imageId);
            log.info("test"+configImgPath + serverFilePath);

            if(serverFilePath=="") {
                return ResponseEntity.notFound().build();
            }

            // to do : 将configImgPath直接换成从db中query
            return ResponseEntity.ok(resourceLoader.getResource( configImgPath + serverFilePath));
        } catch (Exception e) {
            return ResponseEntity.notFound().build();
        }
    }
    /**
     * 根据图片id显示单张图片，从DB查出路径，磁盘读取并返回,该方法通过不同参数返回不同图片
     * @return produces = MediaType.IMAGE_JPEG_VALUE
     * MediaType.APPLICATION_OCTET_STREAM_VALUE,转移到service里
     */
    @ApiOperation("根据鱼类id以及图片类型type获取能显示的图片数据,如果知道这两个值就可以直接获取图片")
    @ApiImplicitParams({
            @ApiImplicitParam(name="fisheryId",value="fisheryId的值",required=true,paramType="query",dataType="Integer"),
            @ApiImplicitParam(name="imageType",value="imageType的值",required=true,paramType="query",dataType="Integer")
    })
    @RequestMapping(method = RequestMethod.GET,value = "/getStreamByTypeAndFisheryId",produces= MediaType.APPLICATION_OCTET_STREAM_VALUE)
    public ResponseEntity displayImagesByFisheryIdAndType(@RequestParam("fisheryId")int fisheryId,@RequestParam("imageType")int imageType){
        //to do :先获取id,在query得到图片的路径，对应替换路径下的图片,在用name得到图片传给b端
        String typeFolder="";
        typeFolder="type"+imageType;
        //String serverFilePath="";
        /*
        根据请求类型得到完整的文件夹路径
         */
        String rootPath = configImgPath;
        rootPath=rootPath+"fishery/"+fisheryId+"/"+typeFolder+"/";
        String imagePathExcludeFile=rootPath.substring(rootPath.indexOf(':')+1, rootPath.length());
        File parentDir = new File(imagePathExcludeFile);
        if(!parentDir.exists()) //如果那个目录不存在先创建目录
        {
            parentDir.mkdirs();
        }
        try {
            //"file:"可以直接写在配置文件里
            // 由于是读取本机的文件，必须要有file：,imgPath是在application配置文件中的路径 +"/"
            //放在linux上可能就不要了
            //废弃该方法，动态获取文件名
            //serverFilePath=fisheryImageService.getImagePathByFisheryIdAndImageType(fisheryId,imageType);
            log.info(rootPath );
            String imageName = FileUtil.getOneFileNameFromFolder(imagePathExcludeFile);
//            if(serverFilePath=="") {
//                return ResponseEntity.notFound().build();
//            }
            // to do : 将imgpath直接换成从db中query

            return ResponseEntity.ok(resourceLoader.getResource( "file:"+imageName));
        } catch (Exception e) {
            log.error(e.getMessage());
            return ResponseEntity.notFound().build();
        }
    }

    /**
     *上传第一类图片保存并返回流给浏览器显示
     * @param fileStream 请求格式 multipart/form-data
     * @RequestParam("file") MultipartFile multipartFile
     * @param fisheryId   fishery controller中拿到的 cookie 值，记录当前的fisheryid
     *                    别漏掉注解 @RequestParam("file")
     * @return 成功流，失败没处理
     * @throws Exception
     */
    @RequestMapping(method = RequestMethod.POST,value = "/imgUploadType1",produces= MediaType.APPLICATION_OCTET_STREAM_VALUE)
    public ResponseEntity imgUploadType1(@RequestParam("file") MultipartFile fileStream,@CookieValue("fisheryId") int fisheryId) throws Exception //, Model model)
    {
        /**
         * 通过设置的那个字符串获得存放图片的目录路径
         * file:找到 取:后面的字符串
         * parentDirPath 存图片的绝对路径（服务器）的前一段  E:/fishery/picture/,去掉file前缀
         *
         */
        String subPath="fishery/"+fisheryId+"/type1/";
        String rootPath = configImgPath;
        //String subPath="fishery1/1/type1/";//直接在配置文件里写三个路径启动时候注入会不会更好??
        //该变量生命为整个类，因此不能直接用他操作
        rootPath=rootPath+subPath;
        String parentDirPath = rootPath.substring(rootPath.indexOf(':')+1, rootPath.length());
        File parentDir = new File(parentDirPath);
        if(!parentDir.exists()) //如果那个目录不存在先创建目录
        {
            parentDir.mkdirs();
        }
        //在这里组装一下字符串就行
        String uploadFileName = fileStream.getOriginalFilename();
        /**
         * //全局配置文件中配置的目录加上文件名
         */
        String oldPath = FileUtil.getOneFileNameFromFolder(parentDirPath);
        /**
         * 如果删除成功但保存失败怎么办，需要事务
         */
        //TODO 保存成功删除原文件，首先获取文件名，再按照文件名删除,第一次如果没图就是这样情况
        if (oldPath != null) {
            File oldFile = new File(oldPath);
            if(oldFile.delete()){
                log.info("删除文件成功");
            }else{
                log.error("删除文件失败");
            }
        }
        fileStream.transferTo(new File(parentDirPath + uploadFileName));
        //fileStream.
        return ResponseEntity.ok(resourceLoader.getResource( rootPath + uploadFileName));
    }


    /**
     *上传第二类图片保存并返回流给浏览器显示
     * @param fileStream 请求格式 multipart/form-data
     * @RequestParam("file") MultipartFile multipartFile
     * @param fisheryId   fishery controller中拿到的 cookie 值，记录当前的fisheryid
     *                    别漏掉注解 @RequestParam("file")
     * @return 成功流，失败没处理
     * @throws Exception
     */
    @RequestMapping(method = RequestMethod.POST,value = "/imgUploadType2",produces= MediaType.APPLICATION_OCTET_STREAM_VALUE)
    public ResponseEntity imgUploadType2(@RequestParam("file") MultipartFile fileStream,@CookieValue("fisheryId") int fisheryId) throws Exception //, Model model)
    {
        /**
         * 通过设置的那个字符串获得存放图片的目录路径
         * file:找到 取:后面的字符串
         * parentDirPath 存图片的绝对路径（服务器）的前一段  E:/fishery/picture/,去掉file前缀
         *
         */
        String subPath="fishery/"+fisheryId+"/type2/";
        String rootPath = configImgPath;
        //String subPath="fishery1/1/type1/";//直接在配置文件里写三个路径启动时候注入会不会更好??
        //该变量生命为整个类，因此不能直接用他操作
        rootPath=rootPath+subPath;
        String parentDirPath = rootPath.substring(rootPath.indexOf(':')+1, rootPath.length());
        File parentDir = new File(parentDirPath);
        if(!parentDir.exists()) //如果那个目录不存在先创建目录
        {
            parentDir.mkdirs();
        }
        //在这里组装一下字符串就行
        String uploadFileName = fileStream.getOriginalFilename();
        /**
         * //全局配置文件中配置的目录加上文件名
         */
        String oldPath = FileUtil.getOneFileNameFromFolder(parentDirPath);
        /**
         * 如果删除成功但保存失败怎么办，需要事务
         */
        //TODO 保存成功删除原文件，首先获取文件名，再按照文件名删除,第一次如果没图就是这样情况
        if (oldPath != null) {
            File oldFile = new File(oldPath);
            if(oldFile.delete()){
                log.info("删除文件成功");
            }else{
                log.error("删除文件失败");
            }
        }
        fileStream.transferTo(new File(parentDirPath + uploadFileName));
        //fileStream.
        return ResponseEntity.ok(resourceLoader.getResource( rootPath + uploadFileName));
    }

    /**
     *上传第二类图片保存并返回流给浏览器显示
     * @param fileStream 请求格式 multipart/form-data
     * @RequestParam("file") MultipartFile multipartFile
     * @param fisheryId   fishery controller中拿到的 cookie 值，记录当前的fisheryid
     *                    别漏掉注解 @RequestParam("file")
     * @return 成功流，失败没处理
     * @throws Exception
     */
    @RequestMapping(method = RequestMethod.POST,value = "/imgUploadType3",produces= MediaType.APPLICATION_OCTET_STREAM_VALUE)
    public ResponseEntity imgUploadType3(@RequestParam("file") MultipartFile fileStream,@CookieValue("fisheryId") int fisheryId) throws Exception //, Model model)
    {
        /**
         * 通过设置的那个字符串获得存放图片的目录路径
         * file:找到 取:后面的字符串
         * parentDirPath 存图片的绝对路径（服务器）的前一段  E:/fishery/picture/,去掉file前缀
         *
         */
        /**
         * 通过设置的那个字符串获得存放图片的目录路径
         * file:找到 取:后面的字符串
         * parentDirPath 存图片的绝对路径（服务器）的前一段  E:/fishery/picture/,去掉file前缀
         *
         */
        String subPath="fishery/"+fisheryId+"/type3/";
        String rootPath = configImgPath;
        //String subPath="fishery1/1/type1/";//直接在配置文件里写三个路径启动时候注入会不会更好??
        //该变量生命为整个类，因此不能直接用他操作
        rootPath=rootPath+subPath;
        String parentDirPath = rootPath.substring(rootPath.indexOf(':')+1, rootPath.length());
        File parentDir = new File(parentDirPath);
        if(!parentDir.exists()) //如果那个目录不存在先创建目录
        {
            parentDir.mkdirs();
        }
        //在这里组装一下字符串就行
        String uploadFileName = fileStream.getOriginalFilename();
        /**
         * //全局配置文件中配置的目录加上文件名
         */
        String oldPath = FileUtil.getOneFileNameFromFolder(parentDirPath);
        /**
         * 如果删除成功但保存失败怎么办，需要事务
         */
        //TODO 保存成功删除原文件，首先获取文件名，再按照文件名删除,第一次如果没图就是这样情况
        if (oldPath != null) {
            File oldFile = new File(oldPath);
            if(oldFile.delete()){
                log.info("删除文件成功");
            }else{
                log.error("删除文件失败");
            }
        }
        fileStream.transferTo(new File(parentDirPath + uploadFileName));
        //fileStream.
        return ResponseEntity.ok(resourceLoader.getResource( rootPath + uploadFileName));
    }


    /**
     * 显示单张图片
     * @return produces = MediaType.IMAGE_JPEG_VALUE
     * MediaType.APPLICATION_OCTET_STREAM_VALUE,转移到service里
     */
//    @RequestMapping(method = RequestMethod.GET, value = "/{fileName}",produces=MediaType.APPLICATION_OCTET_STREAM_VALUE)
//    public ResponseEntity displayPhotosByFileName(@PathVariable("fileName")String fileName){
//            //to do :先获取id,在query得到name,在用name得到图片传给b端
//        try {
//            //"file:"可以直接写在配置文件里
//            // 由于是读取本机的文件，必须要有file：,imgPath是在application配置文件中的路径 +"/"
//            //放在linux上可能就不要了
//
//            log.info(imgPath + fileName);
//            // to do : 将imgpath直接换成从db中query
//
//            return ResponseEntity.ok(resourceLoader.getResource( imgPath + fileName));
//        } catch (Exception e) {
//            return ResponseEntity.notFound().build();
//        }
//    }

}
